import {
  bindCallback,
  bindNodeCallback,
  concatMap,
  defer,
  EMPTY,
  from,
  fromEvent,
  fromEventPattern,
  generate,
  iif,
  interval,
  of,
  range,
  throwError,
  timer,
} from "rxjs";

export function throwErrorDemo() {
  const errObs = throwError(() => {
    const error = new Error("hehhe here is error");
    return error;
  });

  errObs.subscribe((e) => {
    console.log(e);
  });
}

export function timerDemo() {
  const ofObs = of(1, 2, 3);

  // 让下面的程序暂停 3s在执行;
  timer(3000)
    .pipe(concatMap(() => ofObs))
    .subscribe((x) => {
      console.log(x);
    });
}

function addEventFunc(hander: (e: Event) => void) {
  document.addEventListener("click", hander);
}

function removeEventFunc(hander: (e: Event) => void) {
  console.log("this is remove");

  document.removeEventListener("click", hander);
}

export function rangeDemo() {
  const rangeObs = range(1, 100);

  rangeObs.subscribe((x) => {
    console.log(x);
  });
}

export function fromeEventPatterDemo() {
  // 要是只有一个参数的话，那么，这个addEventFunc 就是加入了注册一事件，handler
  // 会有subscribe的回调函数执行;
  const fromEventPartterObs = fromEventPattern(addEventFunc);

  // 这个x 就是 e: Event 事件对象；
  fromEventPartterObs.subscribe((x) => {
    console.log("this is subscribe");
    console.log(x);
  });
}

export function fromeEventPatterDemo2() {
  const fromEventPartterObs = fromEventPattern(addEventFunc, removeEventFunc);

  // will happen
  fromEventPartterObs.subscribe((x) => {
    console.log("this is subscribe");
    console.log(x);
  });
}

export function fromDemo() {
  const fromObs = from([1, 2, 3]);
  //
  // const fromObs = of(1, 2, 3); // 和of 一样的

  // 把数组迭代调用这个subscribe 函数；
  fromObs.subscribe((x) => {
    console.log(x);
  });
}

export function iffDemo() {
  const isFirst = true;

  // of 就是把参数传给subscribe 的参数
  const iifObs = iif(() => isFirst, of("hello word"), EMPTY);

  iifObs.subscribe({
    next(value) {
      console.log(value);
    },
    complete() {
      console.log("this is complete");
    },
  });
}

export function generateDemo() {
  const genObs = generate(
    1,
    (x) => x < 10,
    (x) => x + 1,
    (x) => x * 100, // 把条件为true的值 x * 100 的值传给 subscribe
  );
  genObs.subscribe((x) => {
    // 执行每次条件为 true的 x 的值；
    console.log(x);
  });
}

// deffer 创建一个工厂，用来生产Obserable
export const defferDemo = () => {
  const defferObs = defer(() => {
    return Math.random() > 0.5 ? fromEvent(document, "click") : interval(1000);
  });

  defferObs.subscribe((x) => {
    if (typeof x === "number") {
      console.log("this is number");
      console.log(x);
    } else {
      console.log("this is event");
      console.log(x);

      console.log(x.target);
    }
  });
};

// bindNodeCallback 要传的函数是个特殊的函数，这个返回传类型是个 cb(error: null, result)
export const bindNodeCallbackDemo = () => {
  const someFunction = (
    a: number,
    b: string,
    cb: (error: boolean | null, result: string) => void,
  ) => {
    console.log(a);
    console.log(b);
    cb(null, "mmmmmmm");
  };

  const obs = bindNodeCallback(someFunction);

  obs(1, "yuanyuan.zhang").subscribe((fun) => {
    console.log(fun);
  });
};

//bindCallback 把一个函数转成 observable 类型
export const bindCallbackDemo = () => {
  const obs = bindCallback(function (
    a: number,
    b: string,
    cb: (arg: string) => void,
  ) {
    console.log(a);
    console.log(b);
    cb(a + b + "这是我传的");
  });

  obs(1, "zyy").subscribe((val) => {
    console.log(val);
    console.log("zyy funssss");
  });
};
